package com.bihua.wx.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bihua.common.utils.StringUtils;
import com.bihua.common.core.page.TableDataInfo;
import com.bihua.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.config.WxMpConfigStorage;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bihua.wx.domain.bo.WxAccountBo;
import com.bihua.wx.domain.vo.WxAccountVo;
import com.bihua.wx.domain.WxAccount;
import com.bihua.wx.mapper.WxAccountMapper;
import com.bihua.wx.service.IWxAccountService;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 公众号账号Service业务层处理
 *
 * @author ruoyi
 * @date 2023-05-16
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class WxAccountServiceImpl implements IWxAccountService {

    private final WxAccountMapper baseMapper;

    private final WxMpService wxMpService;

    @PostConstruct
    public void loadWxMpConfigStorages(){
        log.info("加载公众号配置...");
        List<WxAccount> accountList = baseMapper.selectList();
        if (accountList == null || accountList.isEmpty()) {
            log.info("未读取到公众号配置，请在管理后台添加");
            return;
        }
        log.info("加载到{}条公众号配置",accountList.size());
        accountList.forEach(this::addAccountToRuntime);
        log.info("公众号配置加载完成");
    }

    /**
     * 查询公众号账号
     */
    @Override
    public WxAccountVo queryById(String appid){
        return baseMapper.selectVoById(appid);
    }

    /**
     * 查询公众号账号列表
     */
    @Override
    public TableDataInfo<WxAccountVo> queryPageList(WxAccountBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<WxAccount> lqw = buildQueryWrapper(bo);
        Page<WxAccountVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询公众号账号列表
     */
    @Override
    public List<WxAccountVo> queryList(WxAccountBo bo) {
        LambdaQueryWrapper<WxAccount> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<WxAccount> buildQueryWrapper(WxAccountBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<WxAccount> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getName()), WxAccount::getName, bo.getName());
        lqw.eq(bo.getType() != null, WxAccount::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getSecret()), WxAccount::getSecret, bo.getSecret());
        lqw.eq(StringUtils.isNotBlank(bo.getToken()), WxAccount::getToken, bo.getToken());
        lqw.eq(StringUtils.isNotBlank(bo.getAesKey()), WxAccount::getAesKey, bo.getAesKey());
        return lqw;
    }

    /**
     * 新增公众号账号
     */
    @Override
    public Boolean insertByBo(WxAccountBo bo) {
        WxAccount add = BeanUtil.toBean(bo, WxAccount.class);
        boolean validFlag = validEntityBeforeSave(add);
        boolean flag = false;
        if(validFlag){
            flag = baseMapper.insert(add) > 0;
            if (flag) {
                bo.setAppid(add.getAppid());
            }
            this.addAccountToRuntime(add);
        }
        return flag;
    }

    /**
     * 修改公众号账号
     */
    @Override
    public Boolean updateByBo(WxAccountBo bo) {
        WxAccount update = BeanUtil.toBean(bo, WxAccount.class);
        boolean validFlag = validEntityBeforeSave(update);
        boolean flag = false;
        if(!validFlag){
            wxMpService.removeConfigStorage(update.getAppid());
            this.addAccountToRuntime(update);
            flag = baseMapper.updateById(update) > 0;
        }
        return flag;
    }

    /**
     * 保存前的数据校验
     */
    private boolean validEntityBeforeSave(WxAccount entity){
        //TODO 做一些数据校验,如唯一约束
        WxAccount account = baseMapper.selectOne(new LambdaQueryWrapper<WxAccount>().eq(WxAccount::getAppid, entity.getAppid()));
        if (ObjectUtil.isNotEmpty(account)) {
            return false;
        }
        return true;
    }
    /**
     * 添加账号到当前程序，如首次添加需初始化configStorageMap
     * @param entity
     */
    private synchronized void addAccountToRuntime(WxAccount entity){
        String appid = entity.getAppid();
        WxMpDefaultConfigImpl config = entity.toWxMpConfigStorage();
        try {
            wxMpService.addConfigStorage(appid,config);
        }catch (NullPointerException e){
            log.info("需初始化configStorageMap...");
            Map<String, WxMpConfigStorage> configStorages = new HashMap<>(4);
            configStorages.put(appid,config);
            wxMpService.setMultiConfigStorages(configStorages,appid);
        }
    }
    /**
     * 批量删除公众号账号
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        ids.forEach(id-> wxMpService.removeConfigStorage((String) id));
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
